const Sequelize = require('sequelize');
const fs = require('fs');
const moment = require('moment');
const xlsx = require('node-xlsx');
const Op = Sequelize.Op;
const db = require('../model/index');
const { removeEmpty } = require('../lib/utilx');
const User = db.models.User;
const DutyShift = db.models.DutyShift;

/**
 * 字符串转化成 年 月 日 时 分 再换成 UTC标准字符串
 * @param time  2019年09月01日 08:00
 * @return {string}  UTC时间
 * @private
 */
function _transferDateStr(time) {
  let numArr = time.match(/[0-9]+/g);
  let year = parseInt(numArr[0]);
  let month = parseInt(numArr[1]) - 1;    // 月份要减1
  let day = parseInt(numArr[2]);
  let hour = parseInt(numArr[3]);
  let minute = parseInt(numArr[4]);

  return moment([year, month, day, hour, minute]).format();
}

/**
 * 字符串转化成 时 分 秒 再换成 UTC标准字符串
 * @private
 */
function _transferDayStr(time) {
  let numArr = time.match(/[0-9]+/g);
  let hour = parseInt(numArr[0]);
  let minute = parseInt(numArr[1]);
  let second = parseInt(numArr[2]);

  return moment([2019, 7, 1, hour, minute, second]).format();
}

class DutyShiftController {
  async getDutyShiftList(ctx) {
    let { page, limit, keyword, createdAtStart, createdAtEnd, type } = ctx.request.body;
    let where = {
      type
    };
    if( createdAtStart && createdAtEnd ) {
      where = Object.assign(where, {
        createdAt: {
          [Op.gte] : new Date(moment.unix(createdAtStart).startOf('day').unix() * 1000),  // 竟然要 * 1000 = - =
          [Op.lte] : new Date(moment.unix(createdAtEnd).endOf('day').unix() * 1000),
        }
      });
    }
    if( keyword ) {
      where = Object.assign(where, {
        [Op.or] : [{
          teamName: {
            [Op.like] : `%${keyword}%`
          }
        }, {
          workRecord: {
            [Op.like] : `%${keyword}%`
          }
        }, {
          baggageCode: {
            [Op.like] : `%${keyword}%`
          }
        }, {
          airportCode: {
            [Op.like] : `%${keyword}%`
          }
        }, {
          inputLocation: {
            [Op.like] : `%${keyword}%`
          }
        }, {
          findLocation: {
            [Op.like] : `%${keyword}%`
          }
        }, {
          findPerson: {
            [Op.like] : `%${keyword}%`
          }
        }, {
          analyze: {
            [Op.like] : `%${keyword}%`
          }
        }, {
          result: {
            [Op.like] : `%${keyword}%`
          }
        }, {
          firstTailLocation: {
            [Op.like] : `%${keyword}%`
          }
        }, {
          lastTailLocation: {
            [Op.like] : `%${keyword}%`
          }
        }, {
          securityLevel: {
            [Op.like] : `%${keyword}%`
          }
        }, {
          reason: {
            [Op.like] : `%${keyword}%`
          }
        }, {
          baggageFeature: {
            [Op.like] : `%${keyword}%`
          }
        }, {
          remark: {
            [Op.like] : `%${keyword}%`
          }
        }, {
          isNormalLocation: {
            [Op.like] : `%${keyword}%`
          }
        }]
      });
    }
    where = removeEmpty(where);
    let totalCount = await DutyShift.count({
      where
    });
    let dutyShiftList = await DutyShift.findAll({
      where,
      limit: limit === -1 ? undefined : limit,
      offset: limit === -1 ? undefined: limit * ( page - 1 ),
      order: [
        ['createdAt', 'DESC']
      ]
    });

    let ATeamLeader = '';
    let ATeamMembers = await User.findAll({
      attributes: ['username', 'isTeamLeader'],
      where: {
        teamName: 'A组',
        isStop: false,
      }
    });
    ATeamMembers.forEach((user) => {
      if(user.isTeamLeader) {
        ATeamLeader = user.username;
      }
    });

    let BTeamLeader = '';
    let BTeamMembers = await User.findAll({
      attributes: ['username', 'isTeamLeader'],
      where: {
        teamName: 'B组',
        isStop: false,
      }
    });
    BTeamMembers.forEach((user) => {
      if(user.isTeamLeader) {
        BTeamLeader = user.username;
      }
    });

    let CTeamLeader = '';
    let CTeamMembers = await User.findAll({
      attributes: ['username', 'isTeamLeader'],
      where: {
        teamName: 'C组',
        isStop: false,
      }
    });
    CTeamMembers.forEach((user) => {
      if(user.isTeamLeader) {
        CTeamLeader = user.username;
      }
    });

    let DTeamLeader = '';
    let DTeamMembers = await User.findAll({
      attributes: ['username', 'isTeamLeader'],
      where: {
        teamName: 'D组',
        isStop: false,
      }
    });
    DTeamMembers.forEach((user) => {
      if(user.isTeamLeader) {
        DTeamLeader = user.username;
      }
    });

    dutyShiftList = dutyShiftList.map((record) => {
      let teamMembers = [];
      let teamLeader = '';
      switch(record.teamName) {
        case 'A组':
          teamMembers = ATeamMembers;
          teamLeader = ATeamLeader;
          break;
        case 'B组':
          teamMembers = BTeamMembers;
          teamLeader = BTeamLeader;
          break;
        case 'C组':
          teamMembers = CTeamMembers;
          teamLeader = CTeamLeader;
          break;
        case 'D组':
          teamMembers = DTeamMembers;
          teamLeader = DTeamLeader;
          break;
      }
      return Object.assign(record.dataValues, {
        teamLeader,
        teamMembers,
        files: [{
          name: record.fileName,
          url: record.downloadUrl,
        }]
      });
    });

    ctx.body = {
      code: 0,
      msg: {
        totalCount,
        count: dutyShiftList.length,
        dutyShiftList,
      }
    };
  }

  async addDutyShift(ctx) {
    let { dutyShiftContent } = ctx.request.body;
    dutyShiftContent.fileName = (dutyShiftContent.files && dutyShiftContent.files.length) ? dutyShiftContent.files[0].name : null;
    dutyShiftContent.downloadUrl = (dutyShiftContent.files && dutyShiftContent.files.length) ? dutyShiftContent.files[0].url : null;
    delete dutyShiftContent.id;
    dutyShiftContent.createdTime = true;

    await DutyShift.create(dutyShiftContent);

    ctx.body = {
      code: 0,
      msg: {},
    }
  }

  async updateDutyShift(ctx) {
    let { dutyShiftContent } = ctx.request.body;
    let id = dutyShiftContent.id;
    dutyShiftContent.fileName = (dutyShiftContent.files && dutyShiftContent.files.length) ? dutyShiftContent.files[0].name : null;
    dutyShiftContent.downloadUrl = (dutyShiftContent.files && dutyShiftContent.files.length) ? dutyShiftContent.files[0].url : null;
    delete dutyShiftContent.createdTime;
    delete dutyShiftContent.id;

    await DutyShift.update(dutyShiftContent, {
      where: {
        id,
      }
    });

    ctx.body = {
      code: 0,
      msg: {},
    }
  }

  async deleteDutyShift(ctx) {
    let { id } = ctx.request.body;
    await DutyShift.destroy({
      where: {
        id
      }
    });

    ctx.body = {
      code: 0,
      msg: {},
    }
  }

  /**
   * 提取出所给文件的数据
   * @param ctx 请求上下文
   * @return {Promise<void>}
   */
  async analysisFile(ctx) {
    let { filename } = ctx.request.body;
    try {
      let fileBuffer = fs.readFileSync(`${__dirname}/../../files/${filename}`);
      let workSheets = xlsx.parse(fileBuffer);
      let dataArray = workSheets[0].data;
      ctx.body = {
        code: 0,
        msg: {
          dataArray,
        }
      }
    } catch (err) {
      console.error(err);
      ctx.body = {
        code: 0,
        msg: {}
      }
    }
  }

  /**
   * 向数据库中批量导入所给数据
   * @param ctx 请求上下文
   * @return {Promise<void>}
   */
  async importData(ctx) {
    let { data, type } = ctx.request.body;
    switch(type) {
      case 'posun':
        for( let i = 0; i < data.length; i++ ) {  // 把所给数据存储起来
          let ele = data[i];
          let baggageCode = ele[0];
          let airportCode = ele[1];
          let STD = _transferDateStr(ele[2]);
          let inputTime = _transferDateStr(ele[3]);
          let inputLocation = ele[4];
          let findTime = _transferDateStr(ele[5]);
          let findLocation = ele[6];
          let findPerson = ele[7];
          let analyze = ele[8];
          let result = ele[9];

          let e = await DutyShift.create({
            createdTime: true,
            baggageCode,
            airportCode,
            STD,
            inputTime,
            inputLocation,
            findTime,
            findLocation,
            findPerson,
            analyze,
            result,
            type,
          });
        }
        break;

      case 'yichang':
        for( let i = 0; i < data.length; i ++) {
          let ele = data[i];
          let baggageCode = ele[0];
          let airportCode = ele[1];
          let STD = _transferDateStr(ele[2]);
          let inputTime = _transferDateStr(ele[3]);
          let inputLocation = ele[4];
          let findTime = _transferDateStr(ele[5]);
          let findLocation = ele[6];
          let findPerson = ele[7];
          let baggageFeature = ele[8];
          let remark = ele[9];
          console.log(String.prototype.trim.call(ele[10]));
          let isNormalLocation = (String.prototype.trim.call(ele[10]) === '是');
          let analyze = ele[11];

          await DutyShift.create({
            createdTime: true,
            baggageCode,
            airportCode,
            STD,
            inputTime,
            inputLocation,
            findTime,
            findLocation,
            findPerson,
            baggageFeature,
            remark,
            isNormalLocation,
            analyze,
            type,
          });
        }
        break;

      case 'chaxun':
        for ( let i = 0; i < data.length; i ++ ) {
          let ele = data[i];
          let airportCode = ele[0];
          let ETD = _transferDateStr(ele[1]);
          let baggageCode = ele[2];
          let BSM = _transferDateStr(ele[3]);
          let firstTailLocation = ele[4];
          let firstTailTime = _transferDateStr(ele[5]);
          let lastTailLocation = ele[6];
          let lastTailTime = _transferDateStr(ele[7]);
          let securityLevel = ele[8];
          let systemInnerTime = _transferDayStr(ele[9]);
          let reason = ele[10];

          await DutyShift.create({
            createdTime: true,
            airportCode,
            baggageCode,
            ETD,
            BSM,
            firstTailLocation,
            firstTailTime,
            lastTailLocation,
            lastTailTime,
            securityLevel,
            systemInnerTime,
            reason,
            type,
          });
        }
        break;
      default:
        ctx.body = {
          code: -1,
          msg: {
            text: 'Unknown Type'
          },
        };
        return;
    }

    ctx.body = {
      code: 0,
      msg: {}
    }

  }


}

module.exports = new DutyShiftController();
